package org.example.seata.common.core.util;

import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import lombok.experimental.UtilityClass;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 当地日期时间工具类
 *
 * @author hzq
 * @date 2021-01-27 13:15
 */
@UtilityClass
public class LocalDateTimeUtil {

    public final static Map<String, Pattern> patternRegexMap = new HashMap<>();
    /*匹配全数字 时间戳*/
    public final static Pattern timeStampPattern = Pattern.compile("[0-9]*");

    static {
        /*ios 时间格式*/
        patternRegexMap.put("yyyy/MM/dd", Pattern.compile("\\d{4}/\\d{2}/\\d{2}"));
        patternRegexMap.put("yyyy/MM/dd HH:mm:ss", Pattern.compile("\\d{4}/\\d{2}/\\d{2}\\s\\d{2}:\\d{2}:\\d{2}"));
        /*android 时间格式*/
        patternRegexMap.put("yyyy-MM-dd", Pattern.compile("\\d{4}-\\d{2}-\\d{2}"));
        patternRegexMap.put("yyyy-MM-dd HH:mm:ss", Pattern.compile("\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}"));
    }

    /**
     * 解析
     * String --> Date
     * String --> LocalDateTime
     * 字符串解析成日期类型
     *
     * @param str 字符串类型时间
     * @return Class<T>
     */
    @SuppressWarnings("unchecked")
    public static <T> T parseStrToDate(String str, Class<T> requiredType) {

        if (StrUtil.isBlank(str)) return null;

        /*
         * ios 格式
         * android 格式
         */
        for (Map.Entry<String, Pattern> next : LocalDateTimeUtil.patternRegexMap.entrySet()) {
            boolean matches = ReUtil.isMatch(next.getValue(), str);
            if (matches) {
                if (requiredType.isAssignableFrom(Date.class)) {
                    try {
                        return ((T) new SimpleDateFormat(next.getKey()).parse(str));
                    } catch (ParseException ignore) {
                    }
                }
                if (requiredType.isAssignableFrom(LocalDateTime.class)) {
                    return ((T) LocalDateTime.parse(str, DateTimeFormatter.ofPattern(next.getKey())));
                }
                if (requiredType.isAssignableFrom(LocalDate.class)) {
                    return ((T) LocalDate.parse(str, DateTimeFormatter.ofPattern(next.getKey())));
                }
            }
        }

        /*
         * 全数字 当成时间戳来解析
         */
        boolean match = ReUtil.isMatch(LocalDateTimeUtil.timeStampPattern, str);
        if (match) {
            if (requiredType.isAssignableFrom(Date.class)) {
                return ((T) new Date(Long.parseLong(str)));
            }
            if (requiredType.isAssignableFrom(LocalDateTime.class)) {
                return ((T) Instant.ofEpochMilli(Long.parseLong(str)).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
            }
            if (requiredType.isAssignableFrom(LocalDate.class)) {
                return ((T) Instant.ofEpochMilli(Long.parseLong(str)).atZone(ZoneOffset.ofHours(8)).toLocalDate());
            }
        }

        return null;
    }
}
